home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
newsgrp
/
group94a.txt
/
000035_icon-group-sender _Sun Jan 30 18:38:28 1994.msg
< prev
next >
Wrap
Internet Message Format
|
1994-08-19
|
8KB
Received: by cheltenham.cs.arizona.edu; Fri, 4 Feb 1994 09:22:47 MST
Date: 30 Jan 94 18:38:28 GMT
From: noc.near.net!news.delphi.com!usenet@uunet.uu.net (Will Mengarini)
Organization: Delphi (info@delphi.com email, 800-695-4005 voice)
Subject: MS-DOS filename wildcard expander
Message-Id: <19940130.13382812.mengarini@delphi.com>
Sender: icon-group-request@cs.arizona.edu
To: icon-group@cs.arizona.edu
Status: R
Errors-To: icon-group-errors@cs.arizona.edu
Goerwitz>> [...] MS-DOS is dying [...]
In reference to OS rwars, bear in mind that for people who only have
toy computers, only toy OSs are realistic; but with serious hacking we
can do serious work on these tiny machines. I can't program in real C++
on my mighty 286/10; I think the compiles are too slow even on the 486/50
I use at work. On the 286, tho, Icon works fine.
The following patch fixed a bug that looks to me like it should have made
the procedure unusable; I can't understand how it could ever have worked
as originally coded. I'd be interested in hearing from anybody who was able
to successfully use it in its original form, with specifics about the
compilers used to build Icon & the DOS version under which it ran. It'd be
particularly interesting to hear an explanation of why it could have worked.
I suggest this replace the current version in BIPL.
############################################################################
#
# File: dosfiles.icn
#
# Subject: Procedures to get MS-DOS file names
#
# Author: Paul Abrahams Patched by: Will Mengarini
#
# Date: September 24, 1990 Date: We 20 Oct 93
#
############################################################################
#
# dosfiles(pfn) accepts a DOS filename possibly containing wildcards.
# The filename can also include a drive letter and path.
# If the filename ends in "\" or ":", "*.*" is appended.
#
# The result sequence is a sequence of the filenames corresponding to pfn.
#
############################################################################
#
# Requires: MS-DOS extensions
#
############################################################################
#
# Patches:
#
# We 20 Oct 93 Will Mengarini
# I tried dosfiles() using Icon 8.8 under MS-DOS 5.0.
# It always gave I/O Error 3, "Path not found".
# I'd built IconX & IconT using Borland C++ 3.1.
# -- The pointer arithmetic was wrong. My patches caused the
# code to work; they're flagged with "pointer arithmetic wrong: ".
# *The pointer arithmetic was coded based on a correct understanding
# that a 16-bit-mode far pointer (which is 32 bits, 16 each for
# segment & offset) resolves (in real mode) to a 20-bit physical
# address, formed by shifting the 16-bit segment left 1 nybble then
# taking the resulting 20-bit address & adding the 16-bit offset.
# However, on an Intel 80x86 processor this calculation is done in
# hardware; software should almost never do it. This is because
# calculation of a physical address in protected mode is completely
# different, with the segment being used as an index into a segment
# descriptor table; & this addressing difference needs to be
# transparent to most of the object code, so real-mode code can be
# relatively-painlessly converted into protected-mode code. Therefore,
# Intel 80x86 object code always passes around 16-bit-mode far
# pointers as 32-bit values, with the segment & offset each in a
# separate 16-bit register or memory "word" (which is what Intel calls
# what Real Computer people call a "halfword"), so when software must
# convert between a 16-bit-mode far pointer (which is 32 bits) & a
# pair of 16-bit segment & offset values, all 32 bits are significant;
# just plop the 16-bit segment into the upper half of the 32-bit area,
# or extract it from there. BTW, don't use expressions like
# integer_value / 32768 to get the upper 16 bits, since Icon will
# convert that to floating-point arithmetic; use
# ishift( integer_value, -16 ).
# -- The GetSpace() wasn't checked for failure, which could cause
# a null pointer reference.
# -- The GetSpace() had no FreeSpace(), so dosfiles() leaked memory.
# Possible enhancements:
# -- dosfiles() uses whatever the DTA was on entry. Therefore, multiple
# distinct searches can't be in progress simultaneously. Several times
# in professional C/C++ work I've needed that, for searching & also
# for file attribute retrieval (which is done using the same DOS
# call), & I've had to kluge because of runtime libraries that didn't
# support reentrant searching. It could be implemented by allocating
# space for a new DTA & storing the search data in that. However,
# every time the program suspends | returns, it must restore the
# default DTA to what it was on entry, in case some *other* process is
# using that DTA; then, on resumption, it must restore its own DTA
# pointer for its next outcome. FreeSpace() can be called on the
# allocated DTA after the final result has been produced.
# *IPD199.Doc warns that Icon expects its own internal allocations of
# memory blocks to result in contiguous memory, so it's not clear
# whether keeping a GetSpace() allocation around during a nontrivial
# amount of other processing is unsafe.
# -- Each time DOS returns a path name, it also returns all the other
# information about that file that DOS shows in a Dir or Attrib
# command. Somehow this should be accessible to the caller. To
# maintain backward compatibility, dosfiles() could take an optional
# 2nd arg consisting of a string of letters each of which would
# correspond to one element of a returned list of data about the found
# file; for example, dosfiles("*.*", "psdta") would generate, for each
# match of *.*, a list consisting of the full path for the file, its
# size, its creation date, its creation time, & its attribute byte. As
# it does now, &null instead of a string would just mean "generate the
# names", & the results would be strings, not single-element lists
# containing strings (as would be produced by a second arg of "p").
#
############################################################################
procedure dosfiles(pfn)
local asciiz, fnr, prefix, k, name
local ds, dx, result, fnloc, string_block
# Get Disk Transfer Address; filename locn is 30 beyond that.
result := Int86([16r21, 16r2f00] ||| list(7,0))
# pointer arithmetic wrong: fnloc := 16 * result[8] + result[3]+ 30
fnloc := ishift( result[8], 16 ) + result[3] + 30
# Get the generalized filename.
fnr := reverse(pfn)
k := upto("\\:", fnr) | *fnr + 1
prefix := reverse(fnr[k:0])
name := "" ~== reverse(fnr[1:k]) | "*.*"
# Get the first file in the sequence.
asciiz := prefix || name || "\x00"
Poke(string_block := GetSpace(*asciiz), asciiz) |
stop( "dosfiles(): GetSpace() failed." )
# pointer arithmetic wrong: ds := string_block / 16
# pointer arithmetic wrong: dx := string_block % 16
ds := ishift( string_block, -16 )
dx := iand( string_block, 16rffff )
result := Int86([16r21, 16r4e00, 0, 0, dx, 0, 0, 0, ds])
FreeSpace(string_block)
case result[2] of {
0 : {}
18 : fail
default : stop("I/O Error ", result[2])
}
suspend prefix || extract_name(fnloc)
# Get the remaining files in the sequence.
while Int86([16r21, 16r4f00, 0, 0, 0, 0, 0, 0, 0])[2] = 0 do
suspend prefix || extract_name(fnloc)
end
procedure extract_name(fnloc)
local asciiz
asciiz := Peek(fnloc, 13)
return asciiz[1:upto("\x00", asciiz)]
end